package lib.bone.admin.controller.flow;

import cn.dev33.satoken.annotation.SaCheckRole;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lib.bone.admin.anno.WebLog;
import lib.bone.admin.constant.MethodTypeConst;
import lib.bone.common.constant.ResponseCodeConst;
import lib.bone.common.core.domain.PageResultDTO;
import lib.bone.common.core.domain.ResponseDTO;
import lib.bone.flow.domain.dto.FlowDefineAddDTO;
import lib.bone.flow.domain.dto.FlowDefineQueryDTO;
import lib.bone.flow.domain.entity.FlowDefine;
import lib.bone.flow.domain.model.FlowModel;
import lib.bone.flow.domain.vo.FlowDefineVO;
import lib.bone.flow.module.parser.FlowNodeParser;
import lib.bone.flow.service.FlowDefineService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.Optional;

/**
 * @author: kindear
 * @date : 2022-2-15
 */
@Slf4j
@RestController
@RequestMapping("flow")
@Api(tags = "流程定义")
public class FlowDefineController {
    @Autowired
    FlowDefineService flowDefineService;

    @Autowired
    FlowNodeParser flowNodeParser;
    /**
     * 新增流程定义
     */
    @WebLog(module = "bone-flow")
    @PostMapping("define")
    @ApiOperation(value = "新增流程定义",notes = "")
    @SaCheckRole("admin")
    public ResponseDTO<FlowDefine> createFlowDefine(@RequestBody FlowDefineAddDTO dto){
        Optional<FlowDefine> defineOp = flowDefineService.getByDefineCode(dto.getFlowDefineCode());
        if (defineOp.isPresent()){
            return ResponseDTO.wrap(ResponseCodeConst.ERROR_PARAM,"流程定义编码不可重复");
        }
        FlowDefine define = new FlowDefine();
        BeanUtil.copyProperties(dto,define,CopyOptions.create().setIgnoreError(true).setIgnoreNullValue(true));
        return ResponseDTO.succData(flowDefineService.saveOne(define));
    }



    @GetMapping("define")
    @ApiOperation(value = "查询流程定义列表",notes = "")
    public ResponseDTO<PageResultDTO<FlowDefine>> getFlowDefineList(FlowDefineQueryDTO dto){
        Sort sort;
        if(dto.getOrder().equalsIgnoreCase("DESC")){
            sort = Sort.by(Sort.Direction.DESC, dto.getSortBy());
        }else {
            sort = Sort.by(Sort.Direction.ASC, dto.getSortBy());
        }

        // tips : 页码对应 - 1
        Pageable pageable = PageRequest.of(dto.getPageNum() - 1 , dto.getPageSize(), sort);

        FlowDefine define = new FlowDefine();
        BeanUtil.copyProperties(dto,define, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
        Example<FlowDefine> example = Example.of(define);

        //return nepuPaperDictService.getAll(pageable,example);
        return ResponseDTO.succData(flowDefineService.getAll(pageable,example));
    }

    /**
     * 根据ID查询流程定义
     * @param defineId
     * @return
     */
    @GetMapping("define/{defineId}")
    @ApiOperation(value = "查询流程定义[id]",notes = "传入流程定义ID,获取流程定义相关信息")
    public ResponseDTO<FlowDefineVO> getFlowDefine(@PathVariable("defineId") String defineId) throws IOException {

        Optional<FlowDefine> defineOp = flowDefineService.getById(defineId);
        /**
         * 根据条件 -- *
         */
        if(defineOp.isPresent()){
            FlowDefine define = defineOp.get();
            FlowDefineVO flowDefineVO = new FlowDefineVO();
            BeanUtil.copyProperties(define,flowDefineVO, CopyOptions.create().setIgnoreError(true).setIgnoreNullValue(true));
            FlowModel flowModel = flowNodeParser.parser(define.getFlowDefine());
            flowDefineVO.setFlowModel(flowModel);
            return ResponseDTO.succData(flowDefineVO);
        }else {
            return ResponseDTO.wrap(ResponseCodeConst.NOT_FOUND);
        }
    }

    @WebLog(module = "bone-flow",operate = MethodTypeConst.DELETE)
    @DeleteMapping("defines/{defineId}")
    @ApiOperation(value = "删除流程定义",notes = "传入流程定义ID,删除流程定义信息")
    @SaCheckRole("admin")
    public ResponseDTO<FlowDefine> deleteFlowDefine(@PathVariable("defineId") String defineId){
        return flowDefineService.deleteById(defineId);
    }

    /**
     * 根据流程定义码获取
     * @param flowDefineCode
     * @return
     * @throws IOException
     */
    @GetMapping("define/code/{flowDefineCode}")
    @ApiOperation(value = "查询流程定义[code]",notes = "")
    public ResponseDTO<FlowDefineVO> getFlowDefines(@PathVariable("flowDefineCode") String flowDefineCode) throws IOException {
        Optional<FlowDefine> defineOp = flowDefineService.getByDefineCode(flowDefineCode);
        /**
         * 根据条件 -- *
         */
        if(defineOp.isPresent()){
            FlowDefine define = defineOp.get();
            FlowDefineVO flowDefineVO = new FlowDefineVO();
            BeanUtil.copyProperties(define,flowDefineVO, CopyOptions.create().setIgnoreError(true).setIgnoreNullValue(true));
            FlowModel flowModel = flowNodeParser.parser(define.getFlowDefine());
            flowDefineVO.setFlowModel(flowModel);
            return ResponseDTO.succData(flowDefineVO);
        }else {
            return ResponseDTO.wrap(ResponseCodeConst.NOT_FOUND);
        }
    }

}
